<?php
/**
 * 易优CMS
 * ============================================================================
 * 版权所有 2016-2028 海南赞赞网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.eyoucms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 陈风任 <491085389@qq.com>
 * Date: 2020-05-07
 */

namespace app\api\model\v1;

use think\Db;
use think\Cache;
use think\Config;

/**
 * 积分兑换模型
 */
load_trait('controller/Jump');

class ScoreShop extends UserBase
{
    use \traits\controller\Jump;

    //初始化
    protected function initialize()
    {
        // 需要调用`Model`的`initialize`方法
        parent::initialize();
        // 商城订单数据模型
        $this->scoreGoodsModel = model('v1.ScoreGoods');
        $this->shopGoodsModel = model('v1.ShopGoods');

    }


    // 写入兑换的url到缓存
    public function getGoodsUrl($post = [])
    {
        // 检测提交的商品是否可购买
        $this->scoreGoodsModel->detectionGoods($post);

        // 查询条件
        $where = [
            'aid' => $post['product_id'],
            'status' => 1,
            'is_del' => 0,
            'arcrank' => ['>=', 0]
        ];
        $isCount = Db::name('archives')->where($where)->count();
        if (!empty($isCount)) {
            // 强制删除订单创建缓存表数据
            Db::name('shop_order_cookie')->where('users_id', $this->users_id)->where('cookie_type', 2)->delete(true);

            // 对ID和订单号加密，拼装url路径
            $cookieData = [
                'users_id' => $this->users_id,
                'product_id' => $post['product_id'],
                'product_num' => $post['product_num']
            ];
            // 存在规格则执行
            if (!empty($post['spec_value_id']) && 'undefined' != $post['spec_value_id']) $cookieData['spec_value_id'] = $post['spec_value_id'];

            // 将订单缓存写入数据库
            $insert = [
                'users_id' => $this->users_id,
                'cookie_data' => serialize($cookieData),
                'cookie_type' => 2,
                'add_time' => getTime(),
                'update_time' => getTime(),
            ];
            $cookieID = Db::name('shop_order_cookie')->insertGetId($insert);
            if (!empty($cookieID)) {
                // 跳转链接
                $url = '/pages/submitpointOrder/submitpointOrder?cookieID=' . $cookieID;
                $this->success('数据正确', $url);
            } else {
                $this->error('数据异常，请再次兑换');
            }
        } else {
            $this->error('该商品不存在或已下架！');
        }
    }

    // 获取商品信息进行展示
    public function getGoodsBuyPage($cookieID = 0, $userInfo = [], $return = false, $useID = 0, $useScorePay = 0, $useBalancePay = 0)
    {
        if (empty($this->users_id)) $this->error('请先登录');
        // 单个商品立即购买时缓存，购物车提交时为空
        $cacheData = [];
        if (!empty($cookieID)) {
            $where = [
                'cookie_id' => $cookieID,
                'users_id' => $this->users_id,
                'cookie_type' => 2,
            ];
            $cacheData = Db::name('shop_order_cookie')->where($where)->getField('cookie_data');
            $cacheData = !empty($cacheData) ? unserialize($cacheData) : [];
        }

        // 查询商品信息列表(购物车商品 或 立即购买商品)
        $goodsList = $this->scoreGoodsModel->getGoodsBuyList($cacheData, $this->users_id);
        if (empty($goodsList)) $this->error('链接失效，请重新下单');

        // 会员收货地址
        $address = Db::name('shop_address')->where('users_id', $this->users_id)->order('is_default desc')->find();
        // 查询运费模板运费金额
        $shippingFee = 0;
        // 是否提示有商品不在配送区域内
        $allowSubmit = 1;
        if (!empty($address)) {
            // 根据收货地址的城市ID获取本次订单运费
            $resultData = $this->shopGoodsModel->getGoodsShippingFee($goodsList, $address);
            if (!empty($resultData)) {
                $goodsList = !empty($resultData['goodsList']) ? $resultData['goodsList'] : [];
                $allowSubmit = !empty($resultData['allowSubmit']) ? intval($resultData['allowSubmit']) : 0;
                $shippingFee = !empty($resultData['shippingFee']) ? floatval($resultData['shippingFee']) : 0;
                // 如果这个会员所属的等级权益中有包邮则执行
                $shippingFee = !empty($userInfo['postage']) ? 0 : $shippingFee;
            }
        }

        // 会员折扣
//        $usersDiscount = !empty($userInfo['level_discount']) ? strval($userInfo['level_discount']) / strval(100) : 0;
        // 秒杀商品没有会员折扣
//        if (!empty($cacheData['active_time_id'])) $usersDiscount = 0;

        // 商品规格/折扣数据处理
        $goodsList = $this->scoreGoodsModel->getGoodsHandleResult($goodsList);
        if (empty($goodsList)) $this->error('商品库存不足或已过期');

        // 全局参数预设
        $globalParam = $this->getGlobalParam($allowSubmit, $shippingFee);

        // 商品数据整合处理
        $result = $this->scoreGoodsModel->getGoodsPriceHandle($goodsList, $globalParam);
        $goodsList = !empty($result['goodsList']) ? $result['goodsList'] : [];
        $globalParam = !empty($result['globalParam']) ? $result['globalParam'] : [];

        // 获取会员的商品优惠券
//        $goodsCoupon = $this->shopGoodsModel->getGoodsCoupon($goodsList, $this->users_id);

        // 全局参数处理
//        $globalParam = $this->getGlobalParamHandle($globalParam, $useFindCoupon);

        // 默认地址
        if (!empty($address)) {
            $address['region']['shipping_fee'] = $shippingFee;
            $address['region']['province'] = get_province_name($address['province']);
            $address['region']['city'] = get_city_name($address['city']);
            $address['region']['district'] = get_area_name($address['district']);
            $address['region']['detail'] = !empty($address['address']) ? strval($address['address']) : '';
            $address['address_all'] = $address['region']['province'] . $address['region']['city'] . $address['region']['district'] . $address['address'];
        }

        // 追加一个不使用优惠券选项
//        $goodsCoupon['useAllCoupon'] = array_merge([['use_id' => 0, 'coupon_name' => '不使用优惠券']], $goodsCoupon['useAllCoupon']);

        // 积分抵扣逻辑
//        $globalParam['scoreDeductionStatus'] = !empty($this->usersConfig['score_deduction_status']) ? intval($this->usersConfig['score_deduction_status']) : 0;
//        $globalParam['usersScores'] = !empty($userInfo['scores']) ? intval($userInfo['scores']) : 0;
//        $globalParam = $this->getUseScoreHandle($globalParam, $useScorePay);

        // 余额抵扣逻辑
//        $globalParam['usersMoney'] = !empty($userInfo['users_money']) ? unifyPriceHandle($userInfo['users_money']) : 0;
//        $globalParam = $this->getUseBalanceHandle($globalParam, $useBalancePay);

        // 数据返回
        $resultData = [
            'address' => !empty($address) ? $address : [],
            'userInfo' => !empty($userInfo) ? $userInfo : [],
            'goodsList' => !empty($goodsList) ? $goodsList : [],
            'globalParam' => !empty($globalParam) ? $globalParam : [],
            'score_config' => getUsersConfigData('score')
//            'goodsCoupon' => !empty($goodsCoupon) ? $goodsCoupon : [],
//            'useFindCoupon' => !empty($useFindCoupon) ? $useFindCoupon : [],
        ];
        if (!empty($return)) {
            return $resultData;
        } else {
            $this->success('数据正确', null, $resultData);
        }
    }

    // 组装订单流程所需全局信息
    private function getGlobalParam($allowSubmit = 1, $shippingFee = 0)
    {
        $globalParam = [
            // 支付总额
            'orderAmount' => 0,
            // 订单使用现金支付部分(微信支付、支付宝支付)
            'payUseCash' => 0,
            // 订单使用余额支付部分(买家余额)
            'payUseBalance' => 0,
            // 订单使用积分支付部分(积分转化的抵扣额)
            'payUseScores' => 0,
            // 订单使用积分支付部分(积分数，订单商品维权时需要)
            'payUseScoresNum' => 0,
            // 商品总数
            'orderTotalNum' => 0,
            // 商品总额
            'orderTotalAmount' => 0,
            // 是否提示有商品不在配送区域内
            'allowSubmit' => intval($allowSubmit),
            // 订单运费
            'shippingFee' => unifyPriceHandle($shippingFee),
        ];

        return $globalParam;
    }

    // 积分商城订单结算
    public function getScoreOrderPay($post = [], $userInfo = [])
    {
        // 基础判断
        if (empty($this->users_id)) $this->error('请先登录');
        if (empty($post['addrID']) || $post['addrID'] == 'undefined') $this->error('请添加收货地址');


        // 获取订单数据
//        $result = $this->getGoodsBuyPage($post['cookieID'], $userInfo, true, $post['useID'], $post['useScorePay'], $post['useBalancePay']);
        $result = $this->getGoodsBuyPage($post['cookieID'], $userInfo, true, 0, $post['useScorePay'], 0);
        $address = !empty($result['address']) ? $result['address'] : [];
        $goodsList = !empty($result['goodsList']) ? $result['goodsList'] : [];
        $globalParam = !empty($result['globalParam']) ? $result['globalParam'] : [];

        //判断兑换数量是否已经达到
        $exchange_num = Db::name('shop_order_details')->where(['users_id'=>$userInfo['users_id'],'product_id'=>$goodsList[0]['aid']])->where('product_score','>',0)->sum('num');
        $exchange_limit = Db::name('memgift')->where('aid',$goodsList[0]['aid'])->value('limit');
        if ($exchange_num >= $exchange_limit){
            $this->error('兑换数量已达到最大限制!');
        }

        //判断积分够不够
        $scores = Db::name('users')->where('users_id',$userInfo['users_id'])->value('scores');
        if ($scores < $globalParam['payUseScoresNum']){
            $this->error('积分不足,请再努力攒一攒吧!');
        }

        // 添加到订单主表
        $times = getTime();
        $insert = [
            'order_code'         => date('Ymd') . $times . rand(10, 100),
            'users_id'           => $this->users_id,
            'order_status'       => 0,
            'order_terminal'     => 3,
            'order_total_num'    => !empty($globalParam['orderTotalNum']) ? floatval($globalParam['orderTotalNum']) : 0,
            'order_total_amount' => !empty($globalParam['orderTotalAmount']) ? floatval($globalParam['orderTotalAmount']) : 0,
            'shipping_fee'       => !empty($globalParam['shippingFee']) ? floatval($globalParam['shippingFee']) : 0,
            'coupon_price'       => 0,
            'order_amount'       => !empty($globalParam['orderAmount']) ? floatval($globalParam['orderAmount']) : 0,
            'pay_use_cash'       => !empty($globalParam['payUseCash']) ? floatval($globalParam['payUseCash']) : 0,
            'pay_use_balance'    => !empty($globalParam['payUseBalance']) && 1 === intval($post['useBalancePay']) ? floatval($globalParam['payUseBalance']) : 0,
            'pay_use_scores'     => !empty($globalParam['payUseScores']) && 1 === intval($post['useScorePay']) ? floatval($globalParam['payUseScores']) : 0,
            'pay_use_scores_num' => !empty($globalParam['payUseScoresNum']) ? intval($globalParam['payUseScoresNum']) : 0,
            'payment_method'     => 0,
            'pay_time'           => 0,
            'pay_name'           => !empty($globalParam['payUseCash']) ? 'wechat' : 'balance',
            'wechat_pay_type'    => !empty($globalParam['payUseCash']) ? 'WeChatH5' : '',
            'pay_details'        => '',
            'prom_type'          => 0,
            'order_source'       => 30,
            'virtual_delivery'   => '',
            'admin_note'         => '',
            'user_note'          => !empty($post['remark']) ? $post['remark'] : '',
            'add_time'           => $times,
        ];
        // 存在收货地址则追加合并到主表数组
        if (!empty($address)) {
            $insert['city'] = !empty($address['city']) ? intval($address['city']) : '';
            $insert['mobile'] = !empty($address['mobile']) ? strval($address['mobile']) : '';
            $insert['address'] = !empty($address['address']) ? strval($address['address']) : '';
            $insert['province'] = !empty($address['province']) ? intval($address['province']) : '';
            $insert['district'] = !empty($address['district']) ? intval($address['district']) : '';
            $insert['consignee'] = !empty($address['consignee']) ? strval($address['consignee']) : '';
        }
        $orderID = Db::name('shop_order')->insertGetId($insert);
        if (!empty($orderID)) {
            // 追加自增ID
            $insert['order_id'] = $orderID;

            // 查询商品属性
            $aids = get_arr_column($goodsList, 'aid');
            $where = [
                'aid' => ['IN', $aids]
            ];
            $field = 'aid, attr_value';
            $goodsAllAttr = Db::name('shop_product_attr')->field($field)->where($where)->select();
            $goodsAllAttr = !empty($goodsAllAttr) ? group_same_key($goodsAllAttr, 'aid') : [];

            // 商品循环处理
            $upSpecValue = [];
            foreach ($goodsList as $key => $value) {
                // 商品属性处理
                $productAttr = !empty($goodsAllAttr[$value['aid']]) ? $goodsAllAttr[$value['aid']] : [];
                $productAttr = !empty($productAttr) ? implode('；', get_arr_column($productAttr, 'attr_value')) : '';
                // 商品规格、商品属性
                $paramData = [
                    // 商品属性
                    'product_attr' => htmlspecialchars($productAttr),
                    // 商品规格
                    'product_spec' => htmlspecialchars($value['product_spec']),
                ];
                // 订单副表添加数组
                $insertDetails[] = [
                    'order_id'      => $orderID,
                    'users_id'      => $this->users_id,
                    'product_id'    => intval($value['aid']),
                    'spec_value_id' => strval($value['spec_value_id']),
                    'product_name'  => strval($value['title']),
                    'num'           => intval($value['product_num']),
                    'data'          => serialize($paramData),
                    'product_price' => floatval($value['users_price']),
                    'product_score' => floatval($value['score']),
                    'prom_type'     => 0,
                    'litpic'        => strval($value['litpic']),
                    'add_time'      => $times,
                ];

                // 商品库存处理
                $upSpecValue[] = [
                    'aid' => $value['aid'],
                    'value_id' => $value['value_id'],
                    'quantity' => $value['product_num'],
                    'spec_value_id' => $value['spec_value_id'],
                    'order_source' => 30,
                    'order_source_id' => 0,
                ];
            }

            $result = Db::name('shop_order_details')->insertAll($insertDetails);
            if (!empty($result)) {
                // 商品库存、销量处理
                $this->scoreGoodsModel->goodsStockDeduct($upSpecValue);

                // 添加订单操作记录
                AddOrderAction($orderID, $this->users_id);

                // 扣除用于订单支付的积分和余额
                $this->handleOrderBalanceScorePay($insert);

                // 订单选择微信支付
//                if (floatval($insert['pay_use_cash']) > floatval(0)) {
//                    // 订单微信支付接口
//                    // $weChatPay = $this->shopOrderPayModel->getWechatAppletsPay($userInfo['openid'], $insert['order_code'], $insert['pay_use_cash']);
//                    $weChatPay = $this->shopOrderPayModel->getWechatAppletsPay($userInfo['openid'], $insert['order_code'], '0.01');
//                    $result = [
//                        'weChatPay' => $weChatPay,
//                        'orderData' => [
//                            'order_id' => $orderID,
//                            'order_code' => $insert['order_code'],
//                            'pay_use_cash' => $insert['pay_use_cash'],
//                        ]
//                    ];
//
//                    // 已开启的微信订阅消息模板
//                    $where = [
//                        'send_scene' => ['IN', [5, 6]],
//                        'template_code' => ['gt', 0],
//                        'is_open' => 1,
//                    ];
//                    $tmplData = Db::name('weixin_template')->where($where)->order('send_scene asc')->getAllWithIndex('template_id');
//                    $result['tmplData'] = $tmplData;
//
//                    $this->success('正在支付', null, $result);
//                }
//                // 积分+余额抵扣足够，不需要其他支付
//                else if (floatval($insert['pay_use_cash']) <= floatval(0)) {
                    // 订单积分余额支付处理
                    $this->orderBalancePayHandle($insert);
//                }
            } else if (!empty($orderID) && empty($result)) {
                // 订单详情添加失败则删除已添加的订单主表数据
                Db::name('shop_order')->delete($orderID);
                $this->error('积分兑换失败，商品数据有误！');
            }
        }
        $this->error('积分兑换失败，商品数据有误！');
    }

    // 积分商城积分余额支付处理
    public function orderBalancePayHandle($orderData = [])
    {
        $payDetails = [
            'unified_id'     => $orderData['order_id'],
            'unified_number' => $orderData['order_code'],
            'payment_amount' => $orderData['pay_use_scores_num'],
            'payment_type'   => '积分支付'
        ];
        $update = [
            'order_status'    => 1,
            'pay_name'        => 'balance',
            'wechat_pay_type' => '',
            'pay_details'     => serialize($payDetails),
            'pay_time'        => getTime(),
            'update_time'     => getTime()
        ];
        $result = Db::name('shop_order')->where('order_id', $orderData['order_id'])->update($update);
        if (!empty($result)) {
            // 添加订单操作记录
            AddOrderAction($orderData['order_id'], $this->users_id, 0, 1, 0, 1, '支付成功！', '使用积分余额完成支付！');

            // 统计销售额
//            eyou_statistics_data(2);
//            eyou_statistics_data(3, $orderData['pay_use_cash']);

            // 发送站内信给后台
            $pay_method_arr = config('global.pay_method_arr');
            $orderData['pay_method'] = $pay_method_arr['balance'];
            SendNotifyMessage($orderData, 5, 1, 0);

            // 订单支付通知
            $params = [
                'users_id' => $this->users_id,
                'result_id' => $orderData['order_id'],
            ];
            eyou_send_notice(5, $params, ['buyer', 'seller']);

            // 已开启的微信订阅消息模板
            $where = [
                'send_scene' => ['IN', [5, 6]],
                'template_code' => ['gt', 0],
                'is_open' => 1,
            ];
            $tmplData = Db::name('weixin_template')->where($where)->order('send_scene asc')->getAllWithIndex('template_id');

            $this->success('支付完成', '/pages/order/index', ['orderData' => $orderData, 'tmplData' => $tmplData]);
        }
    }

    // 扣除(deduct) or 恢复(restore) 用于订单支付的积分和余额
    public function handleOrderBalanceScorePay($orderData = [], $action = 'deduct')
    {
        // 操作条件
        $where = [
            'users_id' => $this->users_id
        ];
        // 查询会员当前的余额和积分
        $usersData = Db::name('users')->field('users_id, users_money, scores')->where('users_id', $this->users_id)->find();

        // 添加记录
        $times = getTime();
        $update = [
            'update_time' => $times
        ];
        // 处理支付的余额
        if (!empty($orderData['pay_use_balance'])) {
            // 扣除余额
            if ('deduct' === strval($action)) {
                $update['users_money'] = Db::raw('users_money-' . ($orderData['pay_use_balance']));
            }
            // 恢复余额
            else if ('restore' === strval($action)) {
                $update['users_money'] = Db::raw('users_money+' . ($orderData['pay_use_balance']));
            }
        }
        // 处理支付的积分
        if (!empty($orderData['pay_use_scores_num'])) {
            // 扣除积分
            if ('deduct' === strval($action)) {
                $update['scores'] = Db::raw('scores-' . ($orderData['pay_use_scores_num']));
            }
            // 恢复积分
            else if ('restore' === strval($action)) {
                $update['scores'] = Db::raw('scores+' . ($orderData['pay_use_scores_num']));
            }
        }
        // 更新会员余额、积分数据
        $updateID = Db::name('users')->where($where)->update($update);
        if (!empty($updateID)) {
            // 添加会员余额记录
            if (!empty($orderData['pay_use_balance'])) {
                // 扣除余额
                if ('deduct' === strval($action)) {
                    addUsersMoneyLog($orderData['order_code'], $usersData, $orderData['pay_use_balance'], '订单支付', 3);
                }
                // 恢复余额
                else if ('restore' === strval($action)) {
                    addUsersMoneyLog($orderData['order_code'], $usersData, $orderData['pay_use_balance'], '订单退回', 2);
                }
            }
            // 添加会员积分记录
            if (!empty($orderData['pay_use_scores_num'])) {
                // 扣除积分
                if ('deduct' === strval($action)) {
                    $insert = [
                        'type' => 10,
                        'users_id' => $this->users_id,
                        'score' => $orderData['pay_use_scores_num'],
                        'info' => '积分兑换',
                        'remark' => '积分兑换',
                    ];
                    eyou_give_score($insert, 1, false);
                }
                // 恢复积分
                else if ('restore' === strval($action)) {
                    $insert = [
                        'type' => 11,
                        'users_id' => $this->users_id,
                        'score' => $orderData['pay_use_scores_num'],
                        'info' => '积分兑换退回',
                        'remark' => '积分兑换退回',
                    ];
                    eyou_give_score($insert, 2, false);
                }
            }
        }
    }
}